home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 112 / EnigmaAmiga112CD.iso / dalla rivista / awnpipe / awnp / awnp-docs / tutorials / tutorial3.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  11KB  |  396 lines

  1. #include <dos/dos.h>
  2. #include <clib/dos_protos.h>       /* General dos functions...    */
  3. #include <stdio.h>                 /* Std functions [printf()...] */
  4. #include <stdlib.h>                /* Std functions [exit()...]   */
  5. #include <string.h>
  6.  
  7.  
  8. /*We pass 'GP' alot but it allows for multiple GUI's in a single aplication*/
  9.  int main( int argc, char *argv[]);
  10.  int getline(struct GUIpipe * GP);
  11.  __stdargs int topipe(struct GUIpipe * GP, UBYTE * data,...);
  12.  int gperror(struct GUIpipe * GP,int error);
  13.  int buildgui(struct GUIpipe * GP);
  14.  int getevent(struct GUIpipe * GP);
  15.  int gadgets(struct GUIpipe * GP);
  16.  int menu(struct GUIpipe * GP);
  17.  UBYTE * eventstr(struct GUIpipe * GP, int num);
  18.  VOID setdefaults(VOID);
  19.  int updategui(struct GUIpipe * GP);
  20.  int saveform(VOID);
  21.  int loadform(struct GUIpipe * GP);
  22.  
  23. /* This structure is used to magage a GUI*/
  24. /*events information and results from topipe() are kept seperate */
  25.  struct GUIpipe
  26.   {
  27.    BPTR file;
  28.    UBYTE * nextline;
  29.    int count,error;
  30.    int val1,val2,val3,val4,val5,val6;
  31.    UBYTE buf[500],str3[200];
  32.    UBYTE str1[20],result1[50],result2[50];
  33.   };
  34.  
  35. /* the structure to mantain the GUI */
  36.  struct GUIpipe myGP;
  37.  
  38. /* Storage for gadget ID's */
  39.  int namegad,agegad,sexgad,knogad,basgad,aregad,cgad,asmgad,resgad,
  40.  dongad,cangad;
  41.  
  42. /*NEW GADGETS FOR TUTORIAL3*/
  43.  int savegad,loadgad,getfilegad;
  44.  
  45. /* the forms information */
  46.  int age,sex,knowledge,basic,arexx,c,asm;
  47.  UBYTE name[104];
  48.  
  49.  
  50.  int main( int argc, char *argv[] )
  51.   {
  52.    struct GUIpipe * GP = &myGP;
  53.    int stop=0;
  54.    setdefaults();
  55. /*try to build the GUI and use it*/
  56.    if(!buildgui(GP))
  57.     {
  58. /* we disable the savegadget after the gui first opens*/
  59.      topipe(GP,"id %ld dis 1 ref\n",savegad);
  60.  
  61. /* we loop until we are told to stop or an error happens*/
  62.      while(!GP->error&&!stop)
  63.       {
  64. /*send continue to tell the pipe no more modify commands are comming and we
  65. want an event*/
  66.        topipe(GP,"con\n");
  67.  
  68. /* read an event.*/
  69.        getevent(GP);
  70. /*since we have received an event the pipe is now ready to get modify
  71. commands again*/
  72.  
  73. /* the first two letter of each event type are different. For this GUI one
  74. letter would be enough . SASC requires you turn the Multiple Character
  75. Constants option on (MCConstants) .*/
  76.        switch(GP->str1[1]+(GP->str1[0]<<8))
  77.         {
  78.          case('ga'):
  79.          stop=gadgets(GP);
  80.          break;
  81.          case('me'):
  82.          stop=menu(GP);
  83.          break;
  84.          case('cl'):
  85.          printf("Use Closed Window or uses CTRl\\\n");
  86.          stop=1;
  87.          break;
  88.         }
  89.       }
  90.     }
  91.  
  92. /*close the pipe connection*/
  93.    if(GP->file)Close(GP->file);
  94.    exit( 0 );
  95.   }
  96.  
  97. /* read a  line from the pipe*/
  98. /* get rid of the old line if there is one*/
  99.  int getline(struct GUIpipe * GP)
  100.   {
  101.    int in;
  102.    if(GP->nextline)
  103.     {
  104.      GP->count-=(GP->nextline-GP->buf);
  105. memmove(GP->buf,GP->nextline,GP->count);
  106.      GP->nextline=0;
  107.     }
  108. /*read pipe until we have an linefeed*/
  109. while (!(GP->nextline=memchr(GP->buf,'\n',GP->count))) {
  110.  
  111.        if(!(in=Read(GP->file,&(GP->buf[GP->count]),499-GP->count)))
  112.         {
  113. /*error on EOF or lines over 499 chars.*/
  114.          gperror(GP,1);
  115.          return(1);
  116.         }
  117.        GP->count+=in;
  118.       }
  119.  
  120. /* mark the end of line*/
  121.    *GP->nextline++=0;
  122.    return(0);
  123.   }
  124. /*write formated data to the pipe (works like printf),
  125.  read the responce from the pipe and parse it,
  126.  return the value of the second parameter is the responce is ok,
  127.  return 0 if we have a problem*/
  128.  __stdargs int topipe(struct GUIpipe * GP, UBYTE * data,...)
  129.   {
  130.    VFPrintf(GP->file,data,(APTR)(4+(int)(&data)) );
  131.    if(getline(GP)) return(0);
  132.    sscanf(GP->buf,"%50s %50s",GP->result1,GP->result2);
  133.    if(!strcmp(GP->result1,"ok"))return(atoi(GP->result2));
  134.    gperror(GP,2);
  135.    return(0);
  136.   }
  137.  
  138.  
  139. /* GP->error could simply be set rather then calling this routine
  140. but its politer to alert the user somehow */
  141.  int gperror(struct GUIpipe * GP,int error)
  142.   {
  143.    GP->error=error;
  144.    printf("ERROR %ld\n",GP->error);
  145.    return(0);
  146.   }
  147.  
  148. /*open the file on AWNPipe:, send the window and gadget definitions,
  149.  open the GUI window, return 0 for sucess or an error number*/
  150.  buildgui(struct GUIpipe * GP)
  151.   {
  152. /* Open pipe 'tut3' with GUI creation option '/xc' */
  153.    if(!( GP->file=Open("awnpipe:tut3/xc",MODE_OLDFILE))) return(1);
  154.  
  155.    /* The first line of every GUI is the window definition. The window is titled
  156. "Tutorial 3" and its elements will be laid out verticaly (v). It has a
  157. closegadget (cg) , depthgadget (dg) , and dragbar (db). It will have spaces
  158. inbetween its gadgets (si). It will open on the topleft (tl) of the screen
  159. becoming active (a) when opened. The GUI can be modified (m)*/
  160.  
  161.    topipe(GP," \"Tutorial 3\" v cg dg db si a tl m\n");
  162.  
  163.    /* define the gadgets*/
  164.    /* Labels are used to tell the user what information to enter in each gadget.
  165. These labels are unatached (ua) when they are defined so don't go directly
  166. into the GUI. Instead they are attached to the following gadget by the
  167. childlabel (chl) keyword. */
  168.  
  169.    topipe(GP," layout b 0 v\n");
  170.    topipe(GP," label gt \"Name: \" ua\n");
  171.    namegad=topipe(GP,"string lj chl\n");
  172.    topipe(GP," label gt \"Age: \" ua\n");
  173.    agegad=topipe(GP,"integer chl minn 10 maxn 99 arrows defn 30  weiw 0\n");
  174.    topipe(GP," label gt \"Sex: \" ua\n");
  175.    sexgad=topipe(GP,"radiobutton rl \"Male|Female\" chl\n");
  176.    topipe(GP," label gt \"Knowledge: \" ua\n");
  177.    knogad=topipe(GP,"chooser pu cl \"Novice|Average|Good|Expert\" chl\n");
  178.    topipe(GP," label gt \"Language(s): \" ua\n");
  179.    topipe(GP," layout b 0 chl\n");
  180.    basgad=topipe(GP,"checkbox gt \"Basic \" chl\n");
  181.    aregad=topipe(GP,"checkbox gt \"Arexx \" chl\n");
  182.    cgad=topipe(GP,"checkbox gt \"C \" chl\n");
  183.    asmgad=topipe(GP,"checkbox gt \"ASM \" chl\n");
  184.    topipe(GP," le\n");
  185.    topipe(GP," le\n");
  186.    topipe(GP," layout si so\n");
  187.    savegad= topipe(GP,"button gt \"Save\" \n");
  188.    loadgad= topipe(GP,"button gt \"Load\" \n");
  189.    resgad= topipe(GP,"button gt \"Reset Form\" \n");
  190.    dongad= topipe(GP,"button gt \"Done\" c\n");
  191.    cangad= topipe(GP,"button gt \"Cancel\" c\n");
  192.    topipe(GP," le\n");
  193.    topipe(GP," menu gt \"Project  |About|$!   Tutorial 2   |$!  AWNPipe: Example\"\n");
  194.    topipe(GP," menu gt \"Data|@AShow all data|Show part|$@PPersonal|$@SSkill\"\n");
  195.  
  196. /* this gadget is unattached so does not show in the GUI. It is used by the
  197. loadform() routine. */
  198.    getfilegad= topipe(GP,"getfile gt \"Select Information File\" fn \"t:\" ua pat \"#?.tut3\" \n");
  199.  
  200.    /*open the GUI window if all is ok*/
  201.    if(!GP->error) topipe(GP,"open\n");
  202.    return(GP->error);
  203.   }
  204.  
  205.  
  206. /* read a line from the pipe and parse it for event information*/
  207.  int getevent(struct GUIpipe * GP)
  208.   {
  209. UBYTE * s3;
  210.    if(!getline(GP))
  211.     {
  212.      sscanf(GP->buf,"%20s %d %d %d %d %d",
  213.             GP->str1,&GP->val2,&GP->val3,
  214.             &GP->val4,&GP->val5,&GP->val6);
  215.      sscanf(GP->buf,"%d",&GP->val1);
  216. if (s3=eventstr(GP,3)){
  217. if (strlen(s3)<200)strcpy(GP->str3,s3);
  218. else memmove(GP->str3,s3,199);
  219.     }
  220. }
  221.    return(GP->error);
  222.   }
  223.  
  224. /* find the start of the 'num' parameter.
  225. ONLY CALL THIS FUCNTION IMEDIATLY AFTER RECEIVING A LINE.
  226. Then store a copy of the string, NOT THE POINTER */
  227.  UBYTE * eventstr(struct GUIpipe * GP,int num)
  228.   {
  229.    UBYTE *a;
  230.    a=GP->buf;
  231.    while((num--)>1)
  232.     {
  233.      a=strchr(a,' ');
  234.      if(!a)return(0);
  235.      a++;
  236.     }
  237.    return(a);
  238.   }
  239.  
  240. /* store the information from the event, or perform an action
  241.  we return 1 if the gui should be closed, or 0 to keep going*/
  242.  int gadgets(struct GUIpipe * GP)
  243.   {
  244.    int a;
  245.    a=GP->val2;
  246.    if(a==agegad)     age=GP->val3;
  247.    if(a==sexgad)     sex=GP->val3;
  248.    if(a==knogad)     knowledge=GP->val3;
  249.    if(a==basgad)     basic=GP->val3;
  250.    if(a==aregad)     arexx=GP->val3;
  251.    if(a==cgad)       c=GP->val3;
  252.    if(a==asmgad)     asm=GP->val3;
  253.    if(a==namegad)
  254.     {
  255.      strcpy(name,GP->str3);
  256. /* disable the save gadget if we do not have a name, enable it if we do*/
  257.      return(topipe(GP,"id %ld dis %ld ref\n",savegad, (strlen(name))?0:1 ));
  258.     }
  259.    if(a==loadgad) return(loadform(GP));
  260.    if(a==savegad) return(saveform());
  261.    if(a==resgad)
  262.     {
  263.      setdefaults();
  264.      return(updategui(GP));
  265.     }
  266.    if(a==cangad)
  267.     {
  268.      printf("User Canceled\n");
  269.      return(1);
  270.     }
  271.    if(a==dongad)
  272.     {
  273.      printf("name: %s\n age: %ld\n sex: %ld\n", name,age,sex);
  274.      printf("knowledge: %ld\n basic: %ld arexx: %ld c: %ld asm: %ld \n",
  275.             knowledge,basic,arexx,c,asm);
  276.      return(1);
  277.     }
  278.    return(0);
  279.   }
  280.  
  281. /*react to the menu event. menu#=val2, menuitem#=val3,subitem#=val4
  282.  menu 0 is only informational so we ignore it and just handle menu 1*/
  283.  int menu(struct GUIpipe * GP)
  284.   {
  285.    if(GP->val2==1)
  286.     {
  287.      if(GP->val3==0)
  288.       {
  289.        printf("name %s age %ld sex %ld\n", name,age,sex);
  290.        printf("knowledge %ld basic %ld arexx %ld c %ld asm %ld \n",
  291.               knowledge,basic,arexx,c,asm);
  292.       }
  293.  
  294.      if(GP->val3==1)
  295.       {
  296.        if(GP->val4==0)
  297.         {
  298.          printf("name %s age %ld sex %ld\n", name,age,sex);
  299.         }
  300.        if(GP->val4==1)
  301.         {
  302.          printf("knowledge %ld basic %ld arexx %ld c %ld asm %ld \n",
  303.                 knowledge,basic,arexx,c,asm);
  304.         }
  305.       }
  306.     }
  307.    return(0);
  308.   }
  309.  
  310. /*initialize our information to default state*/
  311.  VOID setdefaults()
  312.   {
  313.    *name=0;
  314.    age=30;
  315.    sex=0 ;
  316.    knowledge=0;
  317.    basic=0;
  318.    c=0;
  319.    asm=0;
  320.    arexx=0;
  321.   }
  322.  
  323. /* send modify commands to update our GUI to the current information*/
  324.  int updategui(struct GUIpipe * GP)
  325.   {
  326.    topipe(GP,"id %ld defn %ld ref\n",agegad,age);
  327.    topipe(GP,"id %ld s %ld ref\n",sexgad,sex);
  328.    topipe(GP,"id %ld s %ld ref \n",knogad,knowledge);
  329.    topipe(GP,"id %ld s %ld ref\n",basgad,basic);
  330.    topipe(GP,"id %ld s %ld ref\n",aregad,arexx);
  331.    topipe(GP,"id %ld s %ld ref \n",cgad,c );
  332.    topipe(GP,"id %ld s %ld ref\n",asmgad,asm);
  333.    topipe(GP,"id %ld gt \"%ls\" ref\n",namegad,name);
  334.    topipe(GP,"id %ld dis %ld ref\n",savegad,(strlen(name))?0:1);
  335.    return(GP->error);
  336.   }
  337.  
  338. /*write our information to a file. Build the file name from the 'name'
  339. information*/
  340.  int saveform()
  341.   {
  342.    UBYTE buf[300];
  343.    BPTR fh;
  344.    int a;
  345.    if (!strlen(name))return(1);
  346.    a=sprintf(buf,"t:%ls.tut3",name);
  347.    buf[a]=0;
  348.    if(fh=Open(buf,MODE_READWRITE))
  349.     {
  350.      FPrintf(fh,"%ld %ld %ld %ld %ld %ld %ld %ls",
  351.              age ,sex ,knowledge,basic,arexx,c,asm,name);
  352.      Close(fh);
  353.      return(0);
  354.     }
  355.    return(1);
  356.   }
  357.  
  358. /* open our unattached getfile gadget to select a file.
  359. read the file and store the information.*/
  360.  int loadform(struct GUIpipe * GP)
  361.   {
  362.    UBYTE buf[300],*b,*c;
  363.    BPTR fh;
  364.    int a;
  365.    b=buf;
  366.    c=buf;
  367. /* we do not use topipe() since we want to parse the return from this modify
  368. command as an event. This is a special case */
  369.    FPrintf(GP->file,"id %ld fn \"t:\" s 1\n",getfilegad);
  370.    if (getevent(GP)) return(1);
  371. /*val 1 is 0 if the user canceled the file requester, non zero if a file was
  372. selected*/
  373.    if(GP->val1)
  374.     {
  375. /*The file name is returned in quotes. Copy the real file name from between
  376. the quotes. Damn the "Ram Disk:"*/
  377.      if(!(b=eventstr(GP,2))) return(1);
  378.      b++;
  379.      while(*b!='"')*c++=*b++;
  380.      *c++=0;
  381. /*open and read the file, parse the info*/
  382.      if(fh=Open(buf,MODE_OLDFILE))
  383.       {
  384.        a=Read(fh,buf,299);
  385.        buf[a]=0;
  386.        Close(fh);
  387.        sscanf(buf,"%ld %ld %ld %ld %ld %ld %ld",
  388.               &age ,&sex ,&knowledge,&basic,&arexx,&c,&asm);
  389.        strcpy(name,&buf[15]);
  390.        updategui(GP);
  391.       }
  392.     }
  393.    return(0);
  394.   }
  395.  
  396.